var contacts = [];
var pkmax = 0;

var ENTER_KEY = 13;
var PAGEUP_KEY = 33;
var PAGEDOWN_KEY = 34;
var F4_KEY = 115;
var F6_KEY = 117;
var DEL_KEY = 46;

var DEFAULT_ITEM_COLOR = "#000000";
var SELECTED_ITEM_COLOR = "#ff0000";
var selectedID = null;

/******************************************
 * EVENTS
 *****************************************/
function body_Load(event) {
    if (!testLocalStorage())return;
    init();
}

function document_Keydown(event) {
    var evt = window.event||event;
    switch (evt.keyCode) {
        case F6_KEY :
            showContactInfosForNewContact();
            break;
    }
}

function txtSearch_Keydown(event) {
    var evt = window.event||event;
    switch (evt.keyCode) {
        case ENTER_KEY :
            var nodes = _e("contacts").getElementsByTagName("a");
            if (nodes.length > 0) {
                nodes[0].onclick();
            }
            break;
        default:
            setTimeout(function(){showMatches(_e("txtSearch").value)},10);
    }
}

function btnNewContact_Click(event) {
    showContactInfosForNewContact();
}

function btnExport_Click(event) {
    var data = [];
    for (var i=0; i<contacts.length; i++) {
        data.push(JSON.stringify(contacts[i]));
    }
    data = "["+data.join(",")+"]";
    
    useCopyPasteDiv({
        "def_value": data,
        "def_msg": "Copy this data -->",
        "autoselect": true,
        "action_name": "Done",
        "action_handler":
            function(event) {
                hideCopyPaste();
            },
        "uses_cancel_button": false
    });
}

function btnImport_Click(event) {
    useCopyPasteDiv({
        "def_value": "",
        "def_msg": "Paste the data -->",
        "action_name": "Import",
        "action_handler":
            function(event) {
                var data = _e("txaCopyPaste").value;
                contacts = eval(data.replace(/\r\n|\n\r|\n|\r/gm, ""));
                for (var i=0; i<contacts.length; i++) {
                    var key = PK_VALUE_PREFIX+(++pkmax);
                    eval("contacts[i]."+PK.id+"='"+key+"';");
                    localStorage[key] = JSON.stringify(contacts[i]);
                }
                updateList();
                hideCopyPaste();
            },
        "uses_cancel_button": true
    });
}

function btnMerge_Click(event) {
        useCopyPasteDiv({
        "def_value": "",
        "def_msg": "Paste the data -->",
        "action_name": "Merge",
        "action_handler":
            function(event) {
                var data = _e("txaCopyPaste").value;
                contacts = eval(data.replace(/\r\n|\n\r|\n|\r/gm, ""));
                for (var i=0; i<contacts.length; i++) {
                    var key = eval("contacts[i]."+PK.id);
                    localStorage[key] = JSON.stringify(contacts[i]);
                }
                updateList();
                hideCopyPaste();
            },
        "uses_cancel_button": true
    });
}

function btnReplace_Click(event) {
        useCopyPasteDiv({
        "def_value": "",
        "def_msg": "Paste the data -->",
        "action_name": "Replace",
        "action_handler":
            function(event) {
                localStorage.clear();
                var data = _e("txaCopyPaste").value;
                contacts = eval(data.replace(/\r\n|\n\r|\n|\r/gm, ""));
                for (var i=0; i<contacts.length; i++) {
                    var key = eval("contacts[i]."+PK.id);
                    localStorage[key] = JSON.stringify(contacts[i]);
                }
                updateList();
                hideCopyPaste();
            },
        "uses_cancel_button": true
    });
}

function contactInfosDiv_Keydown(event) {
    var evt = window.event||event;
    switch (evt.keyCode) {
        case ENTER_KEY :
            _e("btnFields1").click();
            break;
        case PAGEUP_KEY :
            showPrevContactInfos();
            break;
        case PAGEDOWN_KEY :
            showNextContactInfos();
            break;
        case F4_KEY :
            hideContactInfos();
            break;
        case DEL_KEY :
            if (_e("btnFields2").value.indexOf("Remove")>-1) {
                _e("btnFields2").click();
            }
            break;
    }
}

/******************************************
 * METHODS
 *****************************************/
function init() {
    // UI init
    _e("contactInfosDiv").style.display = "none";
    _e("btnFields3").style.display = "none";
    _e("copyPasteDiv").style.display = "none";
    _e("btnCopyPasteCancel").style.display = "none";
    _e("txtSearch").focus();
    
    // keydown events
    document.onkeydown = document_Keydown;
    _e("contactInfosDiv").onkeydown = contactInfosDiv_Keydown;
    _e("txtSearch").onkeydown = txtSearch_Keydown;
    
    // click events
    _e("btnNewContact").addEventListener("click", btnNewContact_Click, true); // element on top, bubbling fires faster
    _e("btnExport").addEventListener("click", btnExport_Click, true);
    _e("btnImport").addEventListener("click", btnImport_Click, true);
    _e("btnMerge").addEventListener("click", btnMerge_Click, true);
    _e("btnReplace").addEventListener("click", btnReplace_Click, true);
    
    // feed
    fillContacts(); // IMPORTANT!
    _e("contacts").innerHTML = getHtmlContactList("");
    _e("fields").innerHTML = getHtmlFieldList();
}

function useCopyPasteDiv(args) {
    displayCopyPaste();
    _e("txaCopyPaste").value = args.def_value;
    
    if (args.autoselect) {
        _e("txaCopyPaste").select();
    } else {
        _e("txaCopyPaste").focus();
    }
    
    _e("copyPasteMsg").innerText = args.def_msg;
    
    _e("btnCopyPasteOK").value = args.action_name;
    _e("btnCopyPasteOK").onclick = args.action_handler;
    
    if (args.uses_cancel_button) {
        _e("btnCopyPasteCancel").style.display = "";
        _e("btnCopyPasteCancel").value = "Cancel";
        _e("btnCopyPasteCancel").onclick = function(event) {
            hideCopyPaste();
        };
    } else {
        _e("btnCopyPasteCancel").style.display = "none";
    }
}

function displayCopyPaste() {
	_e("contactInfosDiv").style.display = "none";
    _e("copyPasteDiv").style.display = "";
    if (_e("contactInfosDiv").style.display == "none") {
		document.body.style.width = "700px";
		document.body.style.height = "425px";
	}
}

function hideCopyPaste() {
	if (_e("contactInfosDiv").style.display == "none") {
		document.body.style.width = "";
		document.body.style.height = "";
		_e("txtSearch").focus();
    }
	_e("copyPasteDiv").style.display = "none";
}

function fillContacts() {
    contacts = [];
    var sz = localStorage.length;
    for (var i=0; i<sz; i++) {
        var key = localStorage.key(i);
        if (key.substr(0,PK_VALUE_PREFIX.length) == PK_VALUE_PREFIX) {
            var value = JSON.parse(localStorage[key]);
            var idno = parseInt(eval("value."+PK.id).substring(PK_VALUE_PREFIX.length));
            if (idno > pkmax) {
                pkmax = idno;
            }
            contacts.push(value);
        }
    }
    contacts = contacts.sort(byListField0);
}

function byListField0(a,b) {
    var value1 = eval("a."+LIST_FIELDS[0].id);
    var value2 = eval("b."+LIST_FIELDS[0].id);
    return (value1 > value2 ? 1 : -1);
}

function getHtmlContactList(q) {
    selectedID = null; // new list = nothing selected
    var html_content = [];
    var n=0;
    for (var i=0; i<contacts.length; i++) {
        var item = [];
        for (var j=0; j<LIST_FIELDS.length; j++) {
            item.push(eval("contacts[i]."+LIST_FIELDS[j].id));
        }
        
        var match = true;
        if (q != "") {
            var k=0;
            match = false;
            while (k<item.length && !match) {
                match = (item[k].toLowerCase().substr(0,q.length) == q.toLowerCase());
                k++;
            }
        }
                    
        if (match) {
            item = item.join(" ");
			html_content.push([
				"<a id='",CLIST_ID_PREFIX_VALUE,n,"' class='listItem' href='#' onclick='showContactInfos(&quot;",eval("contacts[i]."+PK.id),"&quot;,this)'>",item,"</a><br />"
			].join(""));
            n++;
		}
    }
    if (q != "" && !html_content.length) {
		return "No results";
	}
    return html_content.join("");
}

function showMatches(q) {
	_e("contacts").innerHTML = getHtmlContactList(q);
}

function getHtmlFieldList() {
    var html_content = ["<table id='contactInfos'>"];
    for (var i=0; i<fields.length; i++) {
        html_content.push([
            "<tr>",
            "   <td class='coleft txright'>",fields[i].name," :</td>",
            "   <td class='colright txleft'><input id='",fields[i].id,"' type='text' value='' size='20' /></td>",
            "</tr>"
        ].join(""));
    }
    html_content.push("</table>");
    if (!html_content.length) {
		return "No fields";
	}
    return html_content.join("");
}

function showContactInfos(contactID, sender) {
    displayContactInfos();
    fillContactInfos(contactID);
    
    if (selectedID != null) {
        var selectedNode = _e(CLIST_ID_PREFIX_VALUE+selectedID.toString());
        selectedNode.className = "listItem";
    }
    sender.className = "listItemSelected";

    selectedID = parseInt(sender.id.substr(CLIST_ID_PREFIX_VALUE.length));
    
    _e("btnFields1").value = "Update (Enter)";
    _e("btnFields1").onclick = function(event) {
        updateContactInfo(contactID);
        hideContactInfos();
    };
    
    _e("btnFields2").value = "Remove (Del)";
    _e("btnFields2").onclick = function(event) {
        removeContact(contactID);
        hideContactInfos();
    };
    
    _e("btnFields3").value = "Cancel (F4)";
    _e("btnFields3").onclick = function(event) {
        hideContactInfos();
    };
    _e("btnFields3").style.display = "";
}

function showPrevContactInfos() {
    if (selectedID != null && selectedID > 0) {
        _e(CLIST_ID_PREFIX_VALUE+(selectedID-1)).onclick();
    }
}

function showNextContactInfos() {
    if (selectedID != null && selectedID < _e("contacts").getElementsByTagName("a").length-1) {
        _e(CLIST_ID_PREFIX_VALUE+(selectedID+1)).onclick();
    }
}

function showContactInfosForNewContact() {
    selectedID = null; // new contact = no selection = no prev next
    clearContactInfos();
    
    var newid = PK_VALUE_PREFIX + (pkmax+1);
    _e(PK.id).value = newid;
    displayContactInfos();
    
    _e("btnFields1").value = "Add (Enter)";
    _e("btnFields1").onclick = function(event) {
        var i=0;
        var empty = true;
        while (i<LIST_FIELDS.length && empty) {
            if (_e(LIST_FIELDS[i].id).value != "") {
                empty = false;
            }
            i++;
        }
        if (!empty) {
            updateContactInfo(newid);
            hideContactInfos();
        } else {
            alert("No entry, dammit !");
            _e(FOCUS_START.id).focus();
        }
    };
    
    _e("btnFields2").value = "Cancel (F4)";
    _e("btnFields2").onclick = function(event) {
        hideContactInfos();
    };
    
    _e("btnFields3").style.display = "none"; // button 3 is useless
}

function displayContactInfos() {
	_e("copyPasteDiv").style.display = "none";
    _e("contactInfosDiv").style.display = "";
    _e(PK.id).disabled = true;
    _e(FOCUS_START.id).focus();
    if (_e("copyPasteDiv").style.display == "none") {
	   document.body.style.width = "700px";
	   document.body.style.height = "425px";
	}
}

function hideContactInfos() {
	if (_e("copyPasteDiv").style.display == "none") {
		document.body.style.width = "";
		document.body.style.height = "";
		_e("txtSearch").focus();
	}
	_e("contactInfosDiv").style.display = "none";
    if (selectedID != null) {
        _e(CLIST_ID_PREFIX_VALUE+selectedID.toString()).className = "listItem";
    }
}

function fillContactInfos(contactID) {
    var contact = getContactById(contactID);
    for (var i=0; i<fields.length; i++) {
        var value = eval("contact."+fields[i].id);
        if (value == undefined) {
            value = "";
        }
        _e(fields[i].id).value = value;
    }
}

function clearContactInfos() {
    for (var i=0; i<fields.length; i++) {
        _e(fields[i].id).value = "";
    }
}

function getContactById(id) {
    var obj = null;
    try {
        obj = JSON.parse(localStorage[id]);
    } catch(e) {
        console.log("ContactID '"+id+"' not found");
    }
    return obj;
}

function updateContactInfo(contactID) {
    var contact = {};
    for (var i=0; i<fields.length; i++) {
        eval("contact."+fields[i].id+"=_e(fields[i].id).value");
    }
    localStorage[contactID] = JSON.stringify(contact);
    updateList();
}

function updateList() {
    fillContacts();
    _e("contacts").innerHTML = getHtmlContactList(_e("txtSearch").value);
}

function removeContact(contactID) {
    var msg = "Remove contact '"+_e(CLIST_ID_PREFIX_VALUE+selectedID).innerText+"' ?";
    if (confirm(msg)) {
        try {
            delete localStorage[contactID];
            updateList();
        } catch(e) {
            console.log("contactID '"+contactID+"' cannot be removed");
        }
    }
}

function testLocalStorage() {
    try {
        localStorage["test"] = "test";
        var x = localStorage["test"];
        delete localStorage["test"];
        return true;
    } catch(e) {
        _e("contacts").innerText = "localStorage doesn't work here !";
        return false;
    }
    return;
}

function _e(id) {
    return document.getElementById(id);
}
